import Emitter from "./Emitter.ts";
import TcpSocket from "react-native-tcp-socket";

class TcpClient extends Emitter {
    private heartbeatTimer: NodeJS.Timeout | null = null;
    private reconnectTimer: NodeJS.Timeout | null = null;
    private isManualClose = false;
    private socket: TcpSocket.Socket | undefined | null;
    private host: string | undefined;

    constructor(host: string) {
        super();
        this.host = host;
    }

    private sendHeartbeat() {
        this.send("__ping__");
    }

    private stopHeartbeat() {
        if (this.heartbeatTimer) {
            clearInterval(this.heartbeatTimer);
            this.heartbeatTimer = null;
        }
    }

    send(data: string) {
        if (this.socket && this.socket?.destroyed !== true) {
            this.socket?.write(data);
        }
    }

    start() {
        this.socket = TcpSocket.createConnection({
            host: this.host,
            port: 12345,
            tls: false
        }, () => {
            this.emit("connect", this.host);
            if (this.reconnectTimer) {
                clearTimeout(this.reconnectTimer);
                this.reconnectTimer = null;
            }
            this.stopHeartbeat();
            this.heartbeatTimer = setInterval(() => {
                this.sendHeartbeat();
            }, 3000);
        });
        this.socket?.on("data", (data) => {
            //console.log("Server data:", data);
            const str = data.toString();
            if (str !== '__pong__') {
                this.emit("data", data);
            }
        });
        this.socket?.on("close", () => {
            this.emit("close");
            this.stopHeartbeat();
            if (!this.isManualClose) {
                this.reconnectTimer = setTimeout(() => {
                    this.start();
                }, 3000);
            }
        });
        this.socket?.on("error", (error) => {
            console.log("TCP error:", error);
            this.emit("error", error);
            this.stopHeartbeat();
        });
    }

    stop() {
        this.stopHeartbeat();
        this.socket?.destroy();
        this.socket = null;
        this.isManualClose = true;
        this.heartbeatTimer = null;
    }
}

export default TcpClient;
